--血战到底
--#include "data\config\boss\BloodFightConfig.lua"   once         		--血战到底
--#include "data\config\rule\FuncRulesConfig.lua"   once         		--规则表

BLOODFIGHT_FUBEN_ROOMIDX		= 1 			--副本所属的ROOM的IDX
BLOODFIGHT_FUBEN_BOSSID			= 2 			--副本所属的BOSS的ID
BLOODFIGHT_INSPIRE_TIMES		= 3				--玩家本次副本的鼓舞次数
BLOODFIGHT_FUBEN_STS			= 4 			--副本状态，0-未通关，1-已通关


BloodFightRankColumn = 
{	
	{"name"},				--0，玩家Name
	{"serverId"},			--1，玩家ServerId(留空)
	{"job"},				--2，玩家职业
}

BloodFightWeekRank 		= Lang.Rank.BloodFightWeekRank			--血战到底周榜
BloodFightLastWeekRank	= Lang.Rank.BloodFightLastWeekRank		--血战到底上周榜
--[[
初始化周榜
]]
function InitBloodFightRank()
	--print("*****>>InitAnswerWeekRank...")
	Rank.Init(BloodFightWeekRank, BloodFightWeekRank, BloodFightRankColumn, 1000, 0)
	Rank.Init(BloodFightLastWeekRank, BloodFightLastWeekRank, BloodFightRankColumn, 1000, 0)
end

--[[
注册一些事件
]]
function ResisterBloodFight()
	--print("ResisterBloodFight...")
	SetNeedReloginFuben( BloodFightCfg.fubenId, GlobalLuaConfig.reloginFuben.bloodFightIdx, GetElemsForReLoginBloodFight )
	SceneLogoutDispatcher.register( BloodFightCfg.sceneId, OnCommonFubenLogout )				--注册场景、副本中下线触发的事件
	FubenTimeoutDispatcher.register( BloodFightCfg.fubenId, OnSingleCommonFubenTimeout )		--注册单人场景、副本时间到后触发的事件
	SceneDeathDispatcher.register( BloodFightCfg.sceneId, OnBloodFightActorDeath )				--注册场景、副本中角色死亡触发的事件（非击杀）
	SceneExitDispatcher.register( BloodFightCfg.sceneId,  OnExitBloodFight )					--注册离开场景、副本后触发的事件
	SceneHandExitDispatcher.register( BloodFightCfg.sceneId, OnCommonSceneHandExit )			--注册手工离开场景、副本后触发的事件
end

--[[
离开场景
]]
function OnExitBloodFight( sysarg, sceneId, fubenId )
	--print("OnExitBloodFight, sceneId="..sceneId..", fubenId="..fubenId)
	Actor.collectOperate( sysarg, 0 )  --刷属性
	Actor.collectOperate( sysarg, 3 )  --重置HP

	CloseActivityRightPanel( sysarg )				--关闭右侧面板
end

--[[
角色死亡，结束副本
]]
function OnBloodFightActorDeath( sysarg )
	local sceneId 	= Actor.getSceneId( sysarg )
	local fubenPtr 	= Actor.getFubenPrt(sysarg)
	local fubenId 	= Fuben.getFuBenId(fubenPtr)
	--print("OnBloodFightActorDeath, sceneId="..sceneId..", fubenId="..fubenId)
	--OnBloodFightOver( fubenPtr, 0 )				--
	local fubenHandle = Fuben.getFubenHandle(fubenPtr)
	Fuben.setFubenTime( fubenHandle, 1 )			--关闭副本
end

function IsInBoodFightFuben( fubenId )
	return fubenId == BloodFightCfg.fubenId
end

function IsInBoodFightScene( sysarg )
	local sceneId = Actor.getSceneId( sysarg )
	--print("IsInBoodFightScene, sceneId="..sceneId)
	return sceneId == BloodFightCfg.sceneId
end


--[[
每周一零点处理
]]
function BloodFightMondayProc()
	SendCommonRankAwards( enCommonRankType_BloodFightWeek ) 									--周榜发奖
end
--[[
掉线恢复的一些配置
]]
function GetElemsForReLoginBloodFight( fubenPtr )
	local fubenCfg 				= BloodFightCfg
	local InitFubenRightPanel 	= OnEnterBloodFightEveryTime
	local loginLog   			= "blood fight login" 
	local loginLogOk			= "blood fight login ok" 
	return fubenCfg, InitFubenRightPanel, loginLog, loginLogOk
end


function OpenBloodFightDlg( sysarg )
	--print("OpenBloodFightDlg...")
	local sVar = Actor.getStaticVar(sysarg)
	if not sVar.bloodFightBoss then
		sVar.bloodFightBoss = {}
		FreshBloodFightBoss( sysarg, false )
	end
	SendBloodFightBossInRoom( sysarg )

	local sVar = Actor.getStaticVar(sysarg)
	if not sVar.bloodFightInspire then
		sVar.bloodFightInspire = 0
	end

	SendBloodFightOpReply( sysarg, 1, sVar.bloodFightInspire )
	SendCommonRankSelfData( sysarg, enCommonRankType_BloodFightWeek )
end

--[[
byHand:true-手工刷新，false-自动刷新
]]
function FreshBloodFightBoss( sysarg, byHand )
	--print("FreshBloodFightBoss...")
	if byHand then
		if not BloodFightCfg.freshRoomFee then
			return
		end

		if BloodFightCfg.freshRoomFee.count <= 0 then
			return
		end

		if not CheckConsumeCond( sysarg, { BloodFightCfg.freshRoomFee }, 1 ) then
			return
		end

		if not DoConsumeCond( sysarg, { BloodFightCfg.freshRoomFee }, 1, GameLog.clBloodFreshRoomFee, Lang.ScriptTips.BloodFightLog02 ) then
			return
		end
	end

	local passLevel  = GetActorDailyDoneTimes( sysarg, enDailyOpTimes_BloodFightPass, 0 )			--今日闯关层数
	--print("FreshBloodFightBoss, passLevel="..passLevel)
	local sVar = Actor.getStaticVar(sysarg)
	for roomIdx, room in ipairs( BloodFightCfg.bossForFresh ) do
		local nextPassLevel = passLevel+1
		if nextPassLevel > #room then
			nextPassLevel = #room
		end
		local freshCfg = room[nextPassLevel]
		if freshCfg then
			local idx, elem = GetItemIdxRand( freshCfg )
			if elem and elem.bossIdx then 		--有配置
				sVar.bloodFightBoss[roomIdx] = elem.bossIdx
			else
				sVar.bloodFightBoss[roomIdx] = 1
			end
		end
	end
end


function SendBloodFightBossInRoom( sysarg )
	local sVar = Actor.getStaticVar(sysarg)
	if not sVar.bloodFightBoss then
		return
	end

	local npack = DataPack.allocPacket(sysarg, enBossSystemID, sBloodFightSendRoomBoss)
	if not npack then
		return
	end

	local num = #BloodFightCfg.rooms
	DataPack.writeByte(npack, num)
	for roomIdx=1, #BloodFightCfg.rooms do
		local bossIdx = sVar.bloodFightBoss[roomIdx] or 0
		DataPack.writeByte(npack, roomIdx)
		DataPack.writeByte(npack, bossIdx)
		--print("SendBloodFightBossInRoom, roomIdx="..roomIdx..", bossIdx="..bossIdx)
	end
	DataPack.flush(npack)
end

--[[
进入副本
]]
function EnterBloodFight( sysarg, roomIdx )
	local sVar = Actor.getStaticVar(sysarg)
	if not sVar.bloodFightBoss then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.BloodFight001, ttFlyTip)
		return
	end

	local bossIdx = sVar.bloodFightBoss[roomIdx] or 0
	local  bossCfg = BloodFightCfg.boss[bossIdx]
	if not bossCfg then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.BloodFight001, ttFlyTip)
		return
	end

	if CommonEnterScence( sysarg, BloodFightCfg, 0, "", BloodFightEnterCheck, nil ) then					--以下是初次进入副本
		local passLevel  	= GetActorDailyDoneTimes( sysarg, enDailyOpTimes_BloodFightPass, 0 )			--今日闯关层数
		local newPassLevel 	= passLevel + 1

		local fubenPtr 	= Actor.getFubenPrt( sysarg )
		CreateBloodFightBoss( sysarg, roomIdx, bossIdx )
		Fuben.setFbValue( fubenPtr, BLOODFIGHT_FUBEN_ROOMIDX, roomIdx )			--设置副本的ROOM IDX

		local sVar = Actor.getStaticVar(sysarg)
		local inspireTimes = sVar.bloodFightInspire or 0
		Fuben.setFbValue( fubenPtr, BLOODFIGHT_INSPIRE_TIMES, inspireTimes )	--鼓舞次数记录到副本中，以便掉线恢复
		Fuben.setFbValue( fubenPtr, BLOODFIGHT_FUBEN_STS, 0 )					--未通关

		sVar.bloodFightInspire = nil
		--print("EnterBloodFight, roomIdx="..roomIdx.."newPassLevel="..newPassLevel..", inspireTimes="..inspireTimes)
		OnEnterBloodFightEveryTime( sysarg )

		Actor.triggerAchieveEvent(sysarg, 44, 10, 1)				--触发血战到底成就
	end
end

--[[每次进入，包括初次进入和重登陆恢复
]]
function OnEnterBloodFightEveryTime( sysarg )
	InitBloodFightPanel( sysarg )
	AddBloodFightInspireProp( sysarg )  		--增加鼓舞属性
end

--[[
加鼓舞属性
]]
function AddBloodFightInspireProp( sysarg )
	local fubenPtr 		= Actor.getFubenPrt( sysarg )
	local inspireTimes 	= Fuben.getFbValue( fubenPtr, BLOODFIGHT_INSPIRE_TIMES )
	if inspireTimes <= 0 then
		return
	end
	local propRules = FuncRulesCfg[enFunctionRuleType_BossFightActorProp][1]
	--print("AddBloodFightInspireProp, inspireTimes="..inspireTimes)
	Actor.clearTemporaryAttr( sysarg ) 			--清除临时属性
	for ruleIdx, propRule in ipairs( propRules ) do
		--print("AddBloodFightInspireProp, type="..propRule.type1..", value="..propRule.value)	
		AddTemporaryAttrToEntity( sysarg, propRule.type, propRule.value, inspireTimes )
	end
	Actor.collectOperate( sysarg, 0 )  --刷属性
	Actor.collectOperate( sysarg, 3 )  --重置HP
end

function BloodFightEnterCheck( sysarg )
	--检查闯关次数
	if not CheckActorDailyDoneTimes( sysarg, enDailyOpTimes_BloodFightPass, 0 ) then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.COM0090,ttFlyTip)
		return false
	end
	
	--检查闯关失败次数
	if not CheckActorDailyDoneTimes( sysarg, enDailyOpTimes_BloodFightFail, 0 ) then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.COM0086,ttFlyTip)
		return false
	end
	return true
end

function InitBloodFightPanel( sysarg )
	local contStyle 	= 2					--显示BOSS名称
	local buttons 		= {1}
	local activityId 	= enRightPanelActivity_BloodFight
	local title			= Lang.ScriptTips.BloodFightName

	local fubenPtr 	= Actor.getFubenPrt( sysarg )
	local bossId 	= Fuben.getFbValue( fubenPtr, BLOODFIGHT_FUBEN_BOSSID)
	local bossCfg 	= {}
	bossCfg.monsters= { { monsterId=bossId, sceneId=BloodFightCfg.sceneId, num=1, isBoss=true, }, }
	OpenCommonStylePanel( sysarg, 1, activityId, 0, title, bossCfg, contStyle, buttons  )
end

function CreateBloodFightBoss( sysarg, roomIdx, bossIdx )
	local  bossCfg = BloodFightCfg.boss[bossIdx]
	if not bossCfg then
		return false
	end
	--print("CreateBloodFightBoss, bossIdx="..bossIdx)
	local fubenPtr 		= Actor.getFubenPrt( sysarg )
	local fubenHandle 	= Fuben.getFubenHandle( fubenPtr )
	local sceneHandle  	= Fuben.getSceneHandleById( BloodFightCfg.sceneId, fubenHandle )

	local mon = Fuben.createMonster(sceneHandle, bossCfg.bossId, bossCfg.pos[1], bossCfg.pos[1], bossCfg.livetime)
	if mon then
		--print("CreateBloodFightBoss, bossId="..bossCfg.bossId)
		local fubenPtr = Actor.getFubenPrt( sysarg )
		Fuben.setFbValue( fubenPtr, BLOODFIGHT_FUBEN_BOSSID, bossCfg.bossId )			--设置副本的BOSSID

		local curlevel 	= GetActorDailyDoneTimes( sysarg, enDailyOpTimes_BloodFightPass, 0 ) + 1 			--当前第N关
		local openDays  = System.getDaysSinceOpenServer()
		local propRules = FuncRulesCfg[enFunctionRuleType_BossFightBossProp][roomIdx]
		--print("CreateBloodFightBoss, curlevel="..curlevel..", openDays="..openDays)

		local formulaId = 1 		--公式1， 结果 = nParam1*（（nParam2-1）* nParam3/10000 +开服天数*nParam4/10000 ）	
		Actor.clearTemporaryAttr( mon ) 			--清除临时属性
		for ruleIdx, propRule in ipairs( propRules ) do
			local value = Actor.getIntProperty(mon, propRule.type2) 		--BOSS属性
			--local addValue = math.floor( value * ( ( ( curlevel-1 ) * propRule.param1 ) / 10000 + ( openDays * propRule.param2 ) /10000 ) )
			local addValue = math.floor( System.getFormulaValueById( 1, value, curlevel, propRule.param1, propRule.param2 ) )
			--print("CreateBloodFightBoss,    propType="..propRule.type2..", value="..value..", addValue="..addValue)
			AddTemporaryAttrToEntity( mon, propRule.type1, addValue, 1 )
		end
		Actor.collectOperate( mon,0 )  --刷属性
		Actor.collectOperate( mon,3 )  --重置HP
		return true
	end
	return false
end

--[[
--sysarg:归属玩家
--lastHitKiller：最后一击玩家
注意：怪物死亡时，玩家可能不在线，要确保副本进度能够继续进行
结束副本
]]
function OnBloodFightBossDie( monster, sysarg, monId, lastHitKiller )
	--重置，需要重新刷BOSS
	local sVar = Actor.getStaticVar(sysarg)
	sVar.bloodFightBoss = nil 					--下次需要重新刷
	
	local fubenPtr = Actor.getFubenPrt( monster )
	Fuben.setFbValue( fubenPtr, BLOODFIGHT_FUBEN_STS, 1 )					--已通关

	--OnBloodFightOver( fubenPtr, 1 )
	--print("EnterBloodFight, monId="..monId..", roomIdx="..roomIdx)
	--Actor.exitFuben( sysarg )
	local fubenHandle = Fuben.getFubenHandle(fubenPtr)
	Fuben.setFubenTime( fubenHandle, 1 )			--关闭副本（会触发OnBloodFightOver）
end

--[[
此时玩家可能已经不在副本中了
]]
function OnBloodFightOver( fubenPtr )
	--print( "OnBloodFightOver")
	local ownerId  = Fuben.getOwnerId( fubenPtr )			--副本Owner
	if ownerId <= 0 then
		return
	end

	local actorPtr = System.getEntityPtrByActorID(ownerId)
	if not actorPtr then
		return
	end

	local sts = Fuben.getFbValue( fubenPtr, BLOODFIGHT_FUBEN_STS ) 		--副本是否通关
	--print("OnBloodFightOver, sts="..sts)
	local panelInfo = {}
	panelInfo.sts = sts
	if sts == 1 then
		AddActorDailyDoneTimes( actorPtr, enDailyOpTimes_BloodFightPass, 0, 1 ) 		--通关层数+1
		local roomIdx 	= Fuben.getFbValue( fubenPtr, BLOODFIGHT_FUBEN_ROOMIDX )
		local roomCfg = BloodFightCfg.rooms[roomIdx]
		if not roomCfg then
			return
		end

		local actorId 	= Actor.getActorId( actorPtr )
		local actorName = Actor.getName( actorPtr )
		local job 		= Actor.getIntProperty(actorPtr, PROP_ACTOR_VOCATION)
		local passStar  = roomCfg.passAddStar
		UpdateCommonRankValueById( actorId, BloodFightWeekRank, passStar )
		SetCommonRankActorData( BloodFightWeekRank, actorId, actorName, job )
		SendCommonRankSelfData( actorPtr, enCommonRankType_BloodFightWeek )
		--print("OnBloodFightOver, passStar="..passStar)

		GiveCommonAward(actorPtr, roomCfg.passAwards, GameLog.clBloodPassAward, "blood awards")

		panelInfo.star 	= passStar
		panelInfo.awards = roomCfg.passAwards
		--触发任务
		local passLevel  = GetActorDailyDoneTimes( actorPtr, enDailyOpTimes_BloodFightPass, 0 )			--今日闯关层数
		Actor.triggerQuestEvent(actorPtr, 45, 6, passLevel, false)	
	else
		AddActorDailyDoneTimes( actorPtr, enDailyOpTimes_BloodFightFail, 0, 1 ) 		--失败次数+1
	end
	PassActivityRightPanel( actorPtr, 1, enRightPanelActivity_BloodFight, panelInfo )
end

--[[一些操作
1-鼓舞，2-刷新
]]
function BloodFightOp( sysarg, opType )
	--print( "BloodFightOp, opType="..opType )
	if opType == 1 then 					--鼓舞
		BloodFightInspire( sysarg )
	elseif opType == 2 then 				--手动刷新
		FreshBloodFightBoss( sysarg, true )
		SendBloodFightBossInRoom( sysarg )
	elseif opType == 3 then 					--客户端打开面板时时请求数据
		OpenBloodFightDlg( sysarg )
	end
end

function SendBloodFightOpReply( sysarg, opType, opReplyParam )
	local npack = DataPack.allocPacket(sysarg, enBossSystemID, sBloodFightOpReply)
	if not npack then
		return
	end

	DataPack.writeByte(npack, opType)
	DataPack.writeShort(npack, opReplyParam)
	DataPack.flush(npack)

	--print("SendBloodFightOpReply, opType="..opType..", opReplyParam="..opReplyParam)
end


--[[
鼓舞（此时在副本之外）
]]
function BloodFightInspire( sysarg )
	local sVar = Actor.getStaticVar(sysarg)
	if not sVar.bloodFightInspire then
		sVar.bloodFightInspire = 0
	end
	local newInspireTimes = sVar.bloodFightInspire + 1
	local actorId 	= Actor.getActorId( sysarg )
	local hasPoint 	= GetCommonRankValueById(actorId, BloodFightWeekRank)
	local needPoint	= BloodFightCfg.inspireNeedPoint[newInspireTimes]
	--print("BloodFightInspire, newInspireTimes="..newInspireTimes..", hasPoint="..hasPoint..", needPoint="..needPoint)
	if not needPoint or needPoint < 0 then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.BloodFight002, ttFlyTip)
		return
	end

	if needPoint > hasPoint then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.BloodFight003, ttFlyTip)
		return
	end

	if not UpdateCommonRankValueById( actorId, BloodFightWeekRank, -needPoint ) then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.BloodFight004, ttFlyTip)
		return
	end
	sVar.bloodFightInspire = newInspireTimes
	SendBloodFightOpReply( sysarg, 1, sVar.bloodFightInspire )
	SendCommonRankSelfData( sysarg, enCommonRankType_BloodFightWeek )
end


InitBloodFightRank()

ResisterBloodFight()

